package com.keba.otp.db.mysql;

import java.io.UnsupportedEncodingException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.List;

import org.bouncycastle.util.encoders.Hex;

import com.keba.otp.core.User;
import com.keba.otp.crypto.Crypto;
import com.keba.otp.db.UsersDAO;

/**
 * A MySQL adatbazis Users tablajanak lekerdezesere, modositasara szolgalo DAO 
 * @author bejmuller
 *
 */
public class MySQLUsersDAO implements UsersDAO {

	public MySQLUsersDAO() {
	}
	/**
	 * Visszateriti a tablaban talalhato osszes User-t
	 */
	@Override 
	public List<User> getAllUsers() {
		return null;
	}
	
	/**
	 * Visszateriti a nevnek megfelelo User-t
	 * @param n a megkapni kivant User neve az tablaban
	 */
	@Override
	public User getUserByName(String n) {
		User ret = null;
		Connection conn = null;
		try {
			conn = MySQLConnection.getConnection();
			Statement sm = conn.createStatement();
			ResultSet rs = sm.executeQuery("SELECT * from users WHERE name = \"" + n + "\"");
			rs.first();
			ret = new User(rs.getString(1),rs.getString(2),rs.getString(3),Hex.decode(rs.getString(4)));
			rs.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
		}
		return ret;
	}
	
	
	/**
	 * Beszur egy User-t az abatbazis Users tablajaba
	 * @param u a beszurni kivant User
	 */
	@Override
	public boolean insertUser(User u) {
		
		String name = Crypto.performDecrypt(u.getName(),u.getKey());
		byte[] inBuff = null;
		try {
			inBuff = name.getBytes("utf-8");
		} catch (UnsupportedEncodingException e1) {
			e1.printStackTrace();
		}
		byte[] outBuff = new byte[64];
		org.bouncycastle.crypto.digests.SHA512Digest digest = new org.bouncycastle.crypto.digests.SHA512Digest();
		digest.update(inBuff, 0, inBuff.length);
		int len = digest.doFinal(outBuff, 0);
		String hash = new String(Hex.encode(outBuff, 0, len));
		
		Connection conn = null;
		boolean ret = false;
		try {
			conn = MySQLConnection.getConnection();
			Statement sm = conn.createStatement();
			sm.executeUpdate("INSERT into users VALUES ( \"" + 
					u.getName()  + "\", \"" +
					hash  + "\", \"" +
					u.getPassw() + "\", \"" + 
					new String(Hex.encode(u.getKey()))   + "\", null, null, null, null )");
			ret = true;
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
			ret = false;
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return ret;
	}

	/**
	 * Torli a Usert
	 * @param u a User melyet kell torolni
	 */
	@Override
	public boolean removeUser(User u) {
		Connection conn = null;
		boolean ret = false;
		try {
			conn = MySQLConnection.getConnection();
			Statement sm = conn.createStatement();
			sm.executeUpdate("DELETE FROM users WHERE name_hash = \"" + u.getNameHash() + "\"");
			ret = true;
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return ret;
	}
	
	/**
	 * Frissiti a User jelszavat
	 * @param u a User melynek a jelszavat kell frissiteni
	 */
	@Override
	public boolean updatePassw(User u) {
		Connection conn = null;
		boolean ret = false;
		try {
			conn = MySQLConnection.getConnection();
			User temp = getUserByName(u.getName());
			if (temp != null) {
				Statement sm = conn.createStatement();
				sm.executeUpdate("UPDATE users SET passw = \"" + u.getPassw() + "\" WHERE name = \"" + u.getName() + "\"");
			}
			ret = true;
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return ret;
	}
	
	/**
	 * Frissiti a Userhez hozzarendelt OTP-t, es az OTP letrehozasanak datumat es idejet is
	 * @param u a User melyhez uj OTP-t kell rendelni
	 */
	@Override
	public boolean updateOTP(User u) {
		Connection conn = null;
		boolean ret = false;
		try {
			conn = MySQLConnection.getConnection();
			User temp = getUserByName(u.getName());
			if (temp != null) {
				Statement sm = conn.createStatement();
				sm.executeUpdate("UPDATE users SET otp = \"" + u.getOtp() + "\", otp_create_date = NOW() WHERE name = \"" + u.getName() + "\"");
			}
			ret = true;
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return ret;
	}
	
	/**
	 * Frissiti a User session key-jet, es utolso muveletenek idejet
	 */
	@Override
	public boolean updateSessionKey(User u) {
		Connection conn = null;
		boolean ret = false;
		try {
			conn = MySQLConnection.getConnection();
			User temp = getUserByName(u.getName());
			if (temp != null) {
				Statement sm = conn.createStatement();
				sm.executeUpdate("UPDATE users SET session_key = \"" + u.getSessionKey() + "\", last_access_date = NOW() WHERE name = \"" + u.getName() + "\"");
			}
			ret = true;
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return ret;
	}
	
	/**
	 * Megkeresi a User-t a hozzarendelt session key alapjan
	 * @param sk a session key
	 */
	@Override
	public User getUserBySessionKey(String sk) {
		User ret = null;
		Connection conn = null;
		try {
			conn = MySQLConnection.getConnection();
			Statement sm = conn.createStatement();
			ResultSet rs = sm.executeQuery("SELECT * from users WHERE session_key = \"" + sk + "\"");
			rs.first();
			ret = new User(rs.getString(1),rs.getString(2),rs.getString(3),Hex.decode(rs.getString(4)));
			ret.setSessionKey(rs.getString(7));
			ret.setLastAccessDate(rs.getString(8));
			rs.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
		}
		return ret;
	}
	
	/**
	 * Megkeresi a User-t a hozzarendelt hash alapjan
	 * @param hash a hash
	 */
	@Override
	public User getUserByHash(String hash) {
		User ret = null;
		Connection conn = null;
		try {
			conn = MySQLConnection.getConnection();
			Statement sm = conn.createStatement();
			ResultSet rs = sm.executeQuery("SELECT * from users WHERE name_hash = \"" + hash + "\"");
			rs.first();
			ret = new User(rs.getString(1),rs.getString(2),rs.getString(3),Hex.decode(rs.getString(4)));
			if (rs.getString(5) != null) ret.setOtp(rs.getString(5));
			if (rs.getString(6) != null) ret.setOtpCreateDate(rs.getString(6));
			rs.close();
			conn.close();
		} catch (SQLException e) {
			e.printStackTrace();
		} finally {
			try {
				if (conn != null)
					conn.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
			
		}
		return ret;
	}

}
